<?php


namespace app\service;


use app\entity\ActInfoReviewEntity;
use app\entity\UserEntity;
use app\exception\ErrorCode;
use app\exception\OaException;
use app\models\request\ReqLogin;
use app\models\request\ReqRegister;
use app\models\request\ReqSendCode;
use app\models\request\ReqUpdateInfo;
use app\models\request\ReqUserPage;
use app\models\response\RespLogin;
use app\models\response\RespPage;
use app\models\response\RespUserDetail;
use app\models\UserDto;
use app\utils\JwtUtil;
use PharIo\Manifest\Exception;
use yii\data\Pagination;

class UserService
{

    /**
     * @return mixed|object|\yii\redis\Connection
     */
    public static function getRedis(){
        $redis = \Yii::$app->redis;
        return $redis;
    }


    /**
     * @param $req ReqSendCode
     * @return bool
     * @throws OaException
     */
    public function sendCode($req){



        $redis =  self::getRedis();
        $isSend = false;
        $value = $redis->get($req->getSendKey());
        if (!$value)  $isSend = true;
        if ($isSend) {
            $code = $this->createCode();
            $req->getSendKey();
            $redis->set($req->getSendKey(), $code);
            $redis->expire($req->getSendKey(),60);
            Sms::sendLoginMsg($req->getPhone(),$code);

            $checkNumKey = "ERR_CHECK".$req->getPhone();
            $redis->del($checkNumKey,$checkNumKey."2");


            return true;
        }
        if ($value) {
           throw new OaException(["10003" => "请".$redis->ttl($req->getSendKey())."s后重试"]);
        }
        throw new OaException(["10003" => "请1分钟后重试"]);
    }

    /**
     * @param int $num
     * @return int
     */
    function createCode($num=6) {
        $min = 100000; // 最小值
        $max = 999999; // 最大值
        return rand($min, $max); // 生成随机数字
    }

    /**
     * @param $openId
     * @return array|null|\yii\db\ActiveRecord|UserEntity
     * @throws OaException
     */
    public function findByOpenId($openId) {
        $userEntity = UserEntity::find()->where(["open_id"=>$openId,"del_flag"=>0])->one();
        if(!$userEntity) {
            throw new OaException(ErrorCode::U_A_P_ERR);
        }
        return $userEntity;
    }

    /**
     * @param $phone
     * @return array|\yii\db\ActiveRecord|UserEntity
     * @throws OaException
     */
    public function findByUserName($phone) {
        $userEntity = UserEntity::find()
            ->where(['del_flag' => 0])
            ->andWhere(['user_name' => $phone])
            ->one();

        if(!$userEntity) {
            throw new OaException(ErrorCode::USER_NOT_FOUND);
        }
        return $userEntity;
    }

    /**
     * @param $id
     * @return array|\yii\db\ActiveRecord|UserEntity
     * @throws OaException
     */
    public function findById($id) {
        $userEntity = UserEntity::find()->where(["id"=>$id,"del_flag"=>0])->one();
        if(!$userEntity) {
            throw new OaException(ErrorCode::USER_NOT_FOUND);
        }
        return $userEntity;
    }


    public function findInfoByUserId($userId) {
        return ActInfoReviewEntity::find()->where(["user_id"=>$userId,"type"=>1,"status"=>0,"del_flag"=>0])->one();

    }

    /**
     * @param UserEntity $userEntity
     * @return RespLogin
     */
    public function generateCode(UserEntity $userEntity) {
        $userInfo = new UserDto();
        $userInfo->setUserId($userEntity->getId());
        $userInfo->setUserName($userEntity->getUserName());
        $time = time(); //当前时间
        $token = [
            'iss' => '', //签发者 可选
            'aud' => '', //接收该JWT的一方，可选
            'iat' => $time, //签发时间
            'nbf' => $time , //(Not Before)：某个时间点后才能访问，比如设置time+30，表示当前时间30秒后才能使用
            'exp' => $time+3600*24*365, //过期时间,这里设置2个小时
            'data' => $userInfo
        ];
        $code = JwtUtil::encode($token, \Yii::$app->params["jwtKey"]);
        $resp = new RespLogin();
        $resp->setAuthorization($code);
        return $resp;
    }

    /**
     * @param ReqLogin $req
     * @return RespLogin
     * @throws OaException
     */
    public function login(ReqLogin $req) {
        $userEntity = $this->findByUserName($req->getPhone());
        if ($userEntity->getPassword()!=hash("sha256", $req->getPassword()))
            throw new OaException(ErrorCode::USER_NOT_FOUND);
        return $this->generateCode($userEntity);
    }

    /**
     * @param ReqUpdateInfo $req
     * @return bool
     * @throws OaException
     */
    public function updateInfo(ReqUpdateInfo $req){
        $e = $this->findInfoByUserId($req->getUserId());
        if ($e) {
            throw new OaException(ErrorCode::INFO_SUBMIT);
        }

        $entity = $this->findById($req->getUserId());

        $userEntity = new ActInfoReviewEntity();
        $userEntity->setDelFlag(0);
        $userEntity->setCreateTime(date("Y-m-d G:i:s"));
        $userEntity->setUpdateTime(date("Y-m-d G:i:s"));
        $userEntity->setStatus(0);

        $userEntity->setUserName($entity->getUserName());
        $userEntity->setPassword("");
        $userEntity->setUserEmail($entity->getUserEmail());
        $userEntity->setShopName(strip_tags($req->getShopName()));
        $userEntity->setSchemeType($entity->shop->scheme_type);
        $userEntity->setConnectName(strip_tags($req->getConnectName()));
        $userEntity->setConnectPhone(strip_tags($req->getConnectPhone()));
        $userEntity->setType(1);
        $userEntity->setUserId($req->getUserId());

        $userEntity->setConnectAddress(strip_tags($req->getConnectAddress()));
        $userEntity->setProvince(strip_tags($req->getProvince()));
        $userEntity->setCity(strip_tags($req->getCity()));
        $userEntity->setDistrict(strip_tags($req->getDistrict()));



        $userEntity->save();



      /*  $entity = $this->findById($req->getUserId());
        $entity->setShopName(strip_tags($req->getShopName()));
        $entity->setConnectName(strip_tags($req->getConnectName()));
        $entity->setConnectPhone(strip_tags($req->getConnectPhone()));
        $entity->setConnectAddress(strip_tags($req->getConnectAddress()));
        $entity->setProvince(strip_tags($req->getProvince()));
        $entity->setCity(strip_tags($req->getCity()));
        $entity->setDistrict(strip_tags($req->getDistrict()));
        $entity->save();*/
        return true;
    }

    public function findByUserName1($phone) {
        $userEntity = UserEntity::find()
            ->where(['del_flag' => 0])
            ->andWhere(['user_name' => $phone])
            ->one();

        if(!$userEntity) {
            throw new OaException(ErrorCode::USER_NOT_FOUND);
        }
        return $userEntity;
    }

    public function register(ReqRegister $req) {

        try {
            $userEntity = $this->findByUserName1($req->getUserName());
        }catch (OaException $e) {
            $userEntity = null;
        }
        if ($userEntity) {
            throw new OaException(ErrorCode::USERNAME_EXISTS);
        }
        $userEntity = new ActInfoReviewEntity();
        $userEntity->setDelFlag(0);
        $userEntity->setCreateTime(date("Y-m-d G:i:s"));
        $userEntity->setUpdateTime(date("Y-m-d G:i:s"));
        $userEntity->setStatus(0);

        $userEntity->setUserName($this->sanitize_input($req->getUserName()));
        $userEntity->setPassword(hash("sha256", $req->getPassword()));
        $userEntity->setUserEmail($this->sanitize_input($req->getUserEmail()));
        $userEntity->setShopName($this->sanitize_input($req->getShopName()));
        $userEntity->setSchemeType($this->sanitize_input($req->getSchemeType()));
        $userEntity->setConnectName($this->sanitize_input($req->getConnectName()));
        $userEntity->setConnectPhone($this->sanitize_input($req->getConnectPhone()));
        $userEntity->setMark($this->sanitize_input($req->getMark()));
        $userEntity->setType(0);
        $userEntity->save();
        return true;
    }
    function sanitize_input($input) {
        // 去除输入中的 HTML 和 PHP 标记
        $input = strip_tags($input);

        // 转义特殊字符
        $input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');

        // 返回过滤后的输入
        return $input;
    }
}


